$csCode = @'
//https://social.msdn.microsoft.com/Forums/en-US/0d4737a9-639c-4648-b437-6fcbaee5c2ae/how-do-i-set-the-wallpaper-background-image-per-desktop-monitor?forum=csharpgeneral
//https://devblogs.microsoft.com/oldnewthing/20140314-00/?p=1503
//https://stackoverflow.com/questions/334630/opening-a-folder-in-explorer-and-selecting-a-file/334645
//https://github.com/catwalkagogo/CW.Win32/blob/master/CW.Win32/Shell/ShellItemArray.cs
using System;
using System.Runtime.InteropServices;
public class Wallpaper{
IDesktopWallpaper pDesktopWallpaper = null;
IShellItemArray ppsiItemArray = null;
public Wallpaper()
{
pDesktopWallpaper = (IDesktopWallpaper)(new DesktopWallpaperClass());
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
}
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b63ea76d-1f85-456f-a19c-48159efa858b")]
public interface IShellItemArray
{
}
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
public interface IShellItem
{
}
[ComImport]
[Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IDesktopWallpaper
{
HRESULT SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);
HRESULT GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] ref string wallpaper);
HRESULT GetMonitorDevicePathAt(uint monitorIndex, [MarshalAs(UnmanagedType.LPWStr)] ref string monitorID);
HRESULT GetMonitorDevicePathCount(ref uint count);
HRESULT GetMonitorRECT([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.Struct)] ref RECT displayRect);
HRESULT SetBackgroundColor(uint color);
HRESULT GetBackgroundColor(ref uint color);
HRESULT SetPosition(DESKTOP_WALLPAPER_POSITION position);
HRESULT GetPosition(ref DESKTOP_WALLPAPER_POSITION position);
HRESULT SetSlideshow(IShellItemArray items);
HRESULT GetSlideshow(ref IShellItemArray items);
HRESULT SetSlideshowOptions(DESKTOP_SLIDESHOW_OPTIONS options, uint slideshowTick);
[PreserveSig]
HRESULT GetSlideshowOptions(out DESKTOP_SLIDESHOW_OPTIONS options, out uint slideshowTick);
HRESULT AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, DESKTOP_SLIDESHOW_DIRECTION direction);
HRESULT GetStatus(out DESKTOP_SLIDESHOW_STATE state);
HRESULT Enable(bool benable);
}
public enum DESKTOP_WALLPAPER_POSITION
{
DWPOS_CENTER = 0,
DWPOS_TILE = 1,
DWPOS_STRETCH = 2,
DWPOS_FIT = 3,
DWPOS_FILL = 4,
DWPOS_SPAN = 5
}
public enum DESKTOP_SLIDESHOW_OPTIONS
{
DSO_SHUFFLEIMAGES = 0x1
}
public enum DESKTOP_SLIDESHOW_STATE
{
DSS_ENABLED = 0x1,
DSS_SLIDESHOW = 0x2,
DSS_DISABLED_BY_REMOTE_SESSION = 0x4
}
public enum DESKTOP_SLIDESHOW_DIRECTION
{
DSD_FORWARD = 0,
DSD_BACKWARD = 1
}
[ComImport, Guid("C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD")]
public class DesktopWallpaperClass
{
}
public enum HRESULT : int
{
S_OK = 0,
S_FALSE = 1,
E_NOINTERFACE = unchecked((int)0x80004002),
E_NOTIMPL = unchecked((int)0x80004001),
E_FAIL = unchecked((int)0x80004005)
}
[DllImport("shell32.dll", SetLastError = true)]
public static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, [Out] out IntPtr pidl, uint sfgaoIn, [Out] out uint psfgaoOut);
[DllImport("shell32.dll", SetLastError = true)]
public static extern int SHCreateShellItemArrayFromIDLists(int cidl, IntPtr[] rgpidl, out IShellItemArray ppsiItemArray);
//===========================================================================================================================
public void SetSlideshow(string folderPath)
{
uint psfgaoOut;
var ptrList = new IntPtr[1];
SHParseDisplayName(folderPath, IntPtr.Zero, out ptrList[0], 0, out psfgaoOut);
SHCreateShellItemArrayFromIDLists(1, ptrList, out ppsiItemArray);
pDesktopWallpaper.SetSlideshow(ppsiItemArray);
}
public void SetSlideshowOptions(uint shuffle, uint milliseconds)
{
pDesktopWallpaper.SetSlideshowOptions((DESKTOP_SLIDESHOW_OPTIONS)shuffle, milliseconds);
}
public void SetWallpaper(string filePath)
{
string monitorID = null;
pDesktopWallpaper.GetMonitorDevicePathAt(0, ref monitorID);
pDesktopWallpaper.SetWallpaper(monitorID, filePath);
}
public void SetPosition(uint position)
{
pDesktopWallpaper.SetPosition((DESKTOP_WALLPAPER_POSITION)position);
}
public string GetWallpaper()
{
string monitorID = null;
string filePath = null;
pDesktopWallpaper.GetMonitorDevicePathAt(0, ref monitorID);
pDesktopWallpaper.GetWallpaper(monitorID, ref filePath);
return filePath;
}
public void Enable(bool benable)
{
pDesktopWallpaper.Enable(benable);
}
public uint GetSlideshowOptions()
{
DESKTOP_SLIDESHOW_OPTIONS options;
uint slideshowTick;
pDesktopWallpaper.GetSlideshowOptions(out options, out slideshowTick);
return slideshowTick;
}
public uint GetStatus()
{
DESKTOP_SLIDESHOW_STATE state;
pDesktopWallpaper.GetStatus(out state);
return (uint)state;
}
}
'@
Add-Type -TypeDefinition $csCode
$o = [Wallpaper]::new()
$o.SetWallpaper('C:\new\img0.jpg')
$o.SetSlideshow('C:\picFolder')
#第一個參數:0 按照順序; 1 打亂順序
#第二個參數:圖片變更間隔 milliseconds
$o.SetSlideshowOptions(1, 10000)
#顯示方式
#0:CENTER; 1:TILE; 2:STRETCH; 3:FIT; 4:FILL; 5:SPAN
$o.SetPosition(0)
#0:關閉桌布; 1:啟用桌布
$o.Enable(0)
$Pic = "C:\new\img0.jpg"
$FolderPath = Split-Path $Pic
$FileName = Split-Path $pic -Leaf
$Shell = new-object -com "shell.application"
$File = $Shell.NameSpace($FolderPath).ParseName($FileName)
#WallpaperStyle
#並排 0 而且TileWallpaper要設 1
#置中 0
#延展 2
#全螢幕 6
#填滿 10
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name "WallpaperStyle" -Value "0"
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name "TileWallpaper" -Value "0"
$File.verbs() | ?{ $_.name -like "*(&B)" } | %{ $_.doit() }
# For 英文版 Windows
#$File.verbs() | ?{ $_.name -like "Set as desktop &background" } | %{ $_.doit() }
sleep 2
參考資料:
How do I set the wallpaper / background image per Desktop / Monitor?
How do I create an IShellItemArray from a bunch of file paths? - The Old New Thing
c# - Opening a folder in explorer and selecting a file - Stack Overflow
CW.Win32/ShellItemArray.cs at master · catwalkagogo/CW.Win32 · GitHub